package com.jxt.myjxtmanager.okHttp;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.google.gson.Gson;
import com.jxt.myjxtmanager.R;
import com.jxt.myjxtmanager.manager.ActivityStack;
import com.jxt.myjxtmanager.ui.activity.LoginActivity;
import com.jxt.myjxtmanager.utils.Config;
import com.jxt.myjxtmanager.utils.LogUtils.LogInfo;
import com.jxt.myjxtmanager.utils.PackageUtils;
import com.jxt.myjxtmanager.utils.SharePreferenceUtils.SharedPrefUtil;
import com.jxt.myjxtmanager.utils.SystemInfo;
import com.jxt.myjxtmanager.utils.Tools;
import com.jxt.myjxtmanager.views.DialogView;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.MultipartBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.File;
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Locale;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;


/**
 * Created by Administrator on 2015/12/5 0005.
 * <p>
 * 网络代理
 */
public class HttpClient {

    private final static String TAG = "HttpClient";
    //public static final String API_BASE_DOCTOR = "http://app.1000mob.com";// app域名
    // API域名（正经的）
    //public static final String API_BASE_DOCTOR = "http://app.1000mob.com";// app域名
    //API域名（测）
    public static final String API_BASE_DOCTOR = "http://111.111.11.111:8088";
//    public static final String API_BASE_DOCTOR = "http://101.201.53.142:8088";

    /**
     * 人员登陆
     */
    private static final String API_LOGIN = "/lqjxt/login";
    /**
     * 发送短信申请 获取验证码
     */
    private static final String API_SENDSMS = "/lqjxt/sendSms";
    /**
     * 忘记密码 重设
     */
    private static final String API_RESET_PSW = "/lqjxt/resetPassword";
    /**
     * 首页数据  所有list数据
     */
    private static final String API_BUS_COMPANY_LIST = "/lqjxt/getBusCompanyById";


    private static final String API_CHECK_WORK = "/lqjxt/checkWork";

    ///////////////////////////////////////////////////////////////////////////
    private static final String API_PERSONALINFO = "/lqjxt/personalInfo";
    private static final String API_DEVICES_INFO_STATIS = "/lqjxt/findTeamStatisData";
    private static final String API_CHANGEPASSWORD = "/lqjxt/changePassword";
    ///////////////////////////////////////////////////////////////////////////


    private OkHttpClient client = new OkHttpClient();
    private static HttpClient mInstance;
    private Handler mDelivery;
    private Gson mGson;

    public static HttpClient getInstance() {
        synchronized (HttpClient.class) {
            if (mInstance == null) {
                mInstance = new HttpClient();
            }
        }
        return mInstance;
    }

    private HttpClient() {
        client = new OkHttpClient();
        //cookie enabled
        client.setCookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER));

        client.setConnectTimeout(30000, TimeUnit.MILLISECONDS);
        client.setReadTimeout(30000, TimeUnit.MILLISECONDS);
        client.setWriteTimeout(30000, TimeUnit.MILLISECONDS);
        mDelivery = new Handler(Looper.getMainLooper());
        mGson = new Gson();
    }


    /**
     * 登录
     *
     * @param context
     * @param username
     * @param password
     * @param callback
     */
    public void login(Context context, String username, String password, ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<>();
        mParam.put("phone", username);
        mParam.put("password", Tools.getMD5(password).toLowerCase(Locale.CHINA));
        deliveryResult(context, callback, getOrderParamString(context, API_LOGIN, mParam));
    }

    /**
     * 获取短信验证码
     *
     * @param context
     * @param phone
     * @param callback
     */
    public void GetVerifyCode(Context context, String phone, ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<>();
        mParam.put("phone", phone);
        mParam.put("userMac", SystemInfo.getIMEI(context));
        deliveryResult(context, callback, getOrderParamString(context, API_SENDSMS, mParam));
    }

    /**
     * 重设密码
     *
     * @param context
     * @param phone
     * @param sms
     * @param newPassword
     * @param callback
     */
    public void resetPsw(Context context, String phone, String sms, String newPassword, ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<>();
        mParam.put("phone", phone);
        mParam.put("sms", sms);
        mParam.put("newPassword", Tools.getMD5(newPassword).toLowerCase(Locale.CHINA));
        deliveryResult(context, callback, getOrderParamString(context, API_RESET_PSW, mParam));
    }

    /**
     * 获取首页数据  公司 车队 数据
     *
     * @param context
     * @param busCompanyId
     * @param callback
     */
    public void getBusCompanyById(Context context, String busCompanyId, ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<>();
        mParam.put("busCompanyId", busCompanyId);
        deliveryResult(context, callback, getOrderParamString(context, API_BUS_COMPANY_LIST, mParam));
    }


    ///////////////////////////////////////////////////////////////////////////
    //                   END
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 修改密码
     *
     * @param context
     * @param phone
     * @param oldPassword
     * @param passwordNew
     * @param callback
     */
    public void changepassword(Context context, String phone, String oldPassword, String passwordNew, ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<>();
        mParam.put("phone", phone);
        mParam.put("oldPassword", Tools.getMD5(oldPassword).toLowerCase(Locale.CHINA));
        mParam.put("passwordNew", Tools.getMD5(passwordNew).toLowerCase(Locale.CHINA));
        Log.i(TAG, "changepassword: phone==>" + phone + "oldPassword==>" + oldPassword + "passwordNew==>" + passwordNew);
        deliveryResult(context, callback, getOrderParamString(context, API_CHANGEPASSWORD, mParam));
    }

    /**
     * 车队折线图历史记录
     *
     * @param context
     * @param team_id
     * @param year
     * @param month
     * @param callback
     */
    public void findDeviceRunState(Context context, String team_id, String year, String month,
                                   ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<String, String>();
        mParam.put("team_id", team_id);
        mParam.put("yearStr", year);
        mParam.put("monthStr", month);
        deliveryResult(context, callback, getOrderParamString(context, API_DEVICES_INFO_STATIS,
                mParam));
    }

    /**
     * 个人中心界面
     *
     * @param context
     * @param busCompanyId
     * @param callback
     */
    public void httpMineInfo(Context context, String busCompanyId, ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<>();
        mParam.put("busCompanyId", busCompanyId);
        deliveryResult(context, callback, getOrderParamString(context, API_PERSONALINFO, mParam));
    }

    public void httpCheckWorkInfo(Context context, ResultCallback callback) {
        TreeMap<String, String> mParam = new TreeMap<>();
        deliveryResult(context, callback, getOrderParamString(context, API_CHECK_WORK, mParam));
    }


    /**
     * 请求参数排序
     */
    private Request getOrderParamString(Context context, String url, TreeMap mParam) {
        FormEncodingBuilder builder = new FormEncodingBuilder();
        String timestamp = String.valueOf(System.currentTimeMillis());
        String uuid = SystemInfo.getIMEI(context);
        String version = PackageUtils.getAppVersion(context);
        String app_key = "Qm.inter*connect^app";
        Iterator<String> iter = mParam.keySet().iterator();
        String key;
        while (iter.hasNext()) {
            key = iter.next();
            builder.add(key, String.valueOf(mParam.get(key)));
        }
        String paramsStr = URLEncodedUtils.format(mParam, HTTP.UTF_8);

        String signature = Tools.getMD5(Config.PLATFORM + app_key + uuid + version + paramsStr +
                timestamp);
        LogInfo.d("-----------------------> paramsStr: " + paramsStr);
        return buildRequest(context, builder, API_BASE_DOCTOR + url, version, uuid, signature,
                timestamp);
    }


    /**
     * <br>post异步请求<br>
     * 获取请求头信息
     *
     * @param url
     * @return
     */
    private Request buildRequest(Context cxt, FormEncodingBuilder builder, String url, String
            version, String uuid, String signature, String timestamp) {
        Request request = new Request.Builder()
                .url(url)
                .header("User-Agent", "OkHttp Headers.java")
                .addHeader("Accept", "application/json; q=0.5")
                .addHeader("Accept", "application/vnd.github.v3+json")
                .addHeader("X-VERSION", version)
                .addHeader("X-VerName", version)
                .addHeader("X-VerCode", version)
                .addHeader("X-Platform", Config.PLATFORM)
                .addHeader("X-Device", Build.DEVICE)
                .addHeader("X-Uuid", uuid)
                .addHeader("X-BuildVersion", Build.VERSION.RELEASE)
                .addHeader("timestamp", timestamp)
                .addHeader("signature", signature)
                .addHeader("token", SharedPrefUtil.getInstance(cxt).getString(Config
                        .SHARED_TOKEN, ""))
                .post(builder.build())
                .build();
        LogInfo.d("-----------------------> token: " + SharedPrefUtil.getInstance(cxt).getString
                (Config.SHARED_TOKEN, ""));
        return request;
    }


    /**
     * 上传文件时调用
     *
     * @param cxt
     * @param url
     * @param mParam
     * @param fileKey
     * @param file
     * @return
     */
    private Request buildMultipartFormRequest(Context cxt, String url, TreeMap<String, String>
            mParam, String fileKey, File file) {
        MultipartBuilder builder = new MultipartBuilder()
                .type(MultipartBuilder.FORM);
        Iterator<String> iter = mParam.keySet().iterator();
        String key;
        while (iter.hasNext()) {
            key = iter.next();
//            builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + key + "\""),
//                    RequestBody.create(null, String.valueOf(mParam.get(key))));
            builder.addFormDataPart(key, String.valueOf(mParam.get(key)));
        }

        if (file != null) {
            String fileName = file.getName();
            RequestBody fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)),
                    file);
            builder.addFormDataPart(fileKey, fileName, fileBody);
            //TODO 根据文件名设置contentType
//            builder.addPart(Headers.of("Content-Disposition",
//                            "form-data; name=\"" + fileKey + "\"; filename=\"" + fileName + "\""),
//                    fileBody);
        }
        String timestamp = String.valueOf(System.currentTimeMillis());
        String uuid = SystemInfo.getIMEI(cxt);
        String version = PackageUtils.getAppVersion(cxt);
        String app_key = "Qm.inter*connect^app";
        String signature = Tools.getMD5(Config.PLATFORM + app_key + uuid + version +
                URLEncodedUtils.format(mParam, HTTP.UTF_8) + timestamp);

        Request request = new Request.Builder()
                .url(API_BASE_DOCTOR + url)
                .header("User-Agent", "OkHttp Headers.java")
                .addHeader("Accept", "application/json; q=0.5")
                .addHeader("Accept", "application/vnd.github.v3+json")
                .addHeader("X-VERSION", version)
                .addHeader("X-VerName", version)
                .addHeader("X-VerCode", version)
                .addHeader("X-Platform", Config.PLATFORM)
                .addHeader("X-Device", Build.DEVICE)
                .addHeader("X-Uuid", uuid)
                .addHeader("X-BuildVersion", Build.VERSION.RELEASE)
                .addHeader("timestamp", timestamp)
                .addHeader("signature", signature)
                .addHeader("token", SharedPrefUtil.getInstance(cxt).getString(Config
                        .SHARED_TOKEN, ""))
                .post(builder.build())
                .build();
        return request;
    }

    private String guessMimeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }


    private void deliveryResult(final Context cxt, final ResultCallback callback, Request request) {
        if (!SystemInfo.isNetworkConnected(cxt)) {
            Toast.makeText(cxt, cxt.getString(R.string.toast_not_network), Toast.LENGTH_SHORT).show();
            return;
        }
        if (callback != null) {
            callback.onStart();
        }
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Request request, final IOException e) {
                LogInfo.d("-----------------------> onFailure： " + request.toString());
                onFailuerMessage(callback, request, e);
            }

            @Override
            public void onResponse(final Response response) {
                try {
                    LogInfo.d("--------sss---------------> response： " + response.toString());
                    if (response.code() != 200) {
                        onErrorMessage(callback, response.code(), response.message());
                        return;
                    }
                    String str = response.body().string().toString();
                    LogInfo.d("-----------------------> response.body： " + str);
                    if (!TextUtils.isEmpty(str.trim())) {
                        Result mResult = mGson.fromJson(str, callback.mType);
                        parse(cxt, callback, mResult);
                    }
                } catch (Exception e) {
                    LogInfo.e("parse exception is: " + e.toString());
                }
            }
        });
    }

    /**
     * 服务器没有响应
     *
     * @param callback
     * @param request
     * @param e
     */
    private void onFailuerMessage(final ResultCallback callback, final Request request, final
    IOException e) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                callback.onFailure(request, e);
                callback.onFinish();
            }
        });
    }


    /**
     * 服务器没有响应
     *
     * @param callback
     * @param code
     * @param message
     */
    private void onErrorMessage(final ResultCallback callback, final int code, final String
            message) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                callback.onError(code, message);
                callback.onFinish();
            }
        });
    }

    /**
     * 解析数据
     * 转成主线程回调
     *
     * @param callback
     * @param mResult
     */
    private void parse(final Context cxt, final ResultCallback callback, final Result mResult) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                LogInfo.d("----------------------->mResult.getCode()： " + mResult.getCode());
                if (mResult.getCode() == 1) {       //成功
                    callback.onResponse(mResult);
                    callback.onFinish();
                } else if (mResult.getCode() == 3) {// token失效
                    callback.onFinish();
                    onErrorToken(cxt, mResult.getMsg());
                } else {                            // 失败
                    callback.onResponse(mResult.getCode(), mResult.getMsg());
                    callback.onFinish();
                }
            }
        });
    }

    private void onErrorToken(final Context cxt, String msg) {
        DialogView dialogView = new DialogView(cxt, true);
        dialogView.showDialog(cxt.getString(R.string.toast), msg, new DialogView
                .OnDialogClickListener() {
            @Override
            public void onClick(Dialog dialog) {
                Intent intent = new Intent(cxt, LoginActivity.class);
                cxt.startActivity(intent);
//                BusEnterPriseUserModel.getInstance().ClearSaler();
                ActivityStack.getInstance().popAllActivity(true);
            }
        });

    }


    /**
     * 新改的封装的URl ----->请求参数排序
     *
     * @param context
     * @param url
     * @param mParam
     * @return
     */
    private Request getNewOrderParamString(Context context, String url, TreeMap mParam) {
        FormEncodingBuilder builder = new FormEncodingBuilder();
        String timestamp = String.valueOf(System.currentTimeMillis());
        String uuid = SystemInfo.getIMEI(context);
        String version = PackageUtils.getAppVersion(context);
        String app_key = "Qm.inter*connect^app";
        Iterator<String> iter = mParam.keySet().iterator();
        String key;
        while (iter.hasNext()) {
            key = iter.next();
            builder.add(key, String.valueOf(mParam.get(key)));
        }
        String paramsStr = URLEncodedUtils.format(mParam, HTTP.UTF_8);

        String signature = Tools.getMD5(Config.PLATFORM + app_key + uuid + version + paramsStr +
                timestamp);
        LogInfo.d("-----------------------> paramsStr: " + paramsStr);
        return buildRequest(context, builder, API_BASE_DOCTOR + url, version, uuid, signature,
                timestamp);
    }
}
